<template>
	<view class="out_box">
		<audio ref="audio" controls :src="require('../assets/musics/music.mp3')"></audio>
		<div class="lrc_box" ref="lrcBox">
			<ul class="lrc_list" ref="lrcList" :style="ulStyle">
				<!-- 乱数假文：>lorem加数字（单词个数） -->
				<li class="lrc_word" v-for="(val, index) in lrcArr" :key="index">{{ val.word }}</li>
			</ul>
		</div>
	</view>
</template>

<script>
import lrc from "../common/data.js";

export default {
	name: 'MusicView',
	data() {
		return {
			lrc,
			lrcArr: [],
			currentIndex: -1,
			domInfo: {},
			ulStyle: {
				transform: `translateY(0px)`
			}
		};
	},
	mounted() {
		this.parseLrc();
		this.setListenerEvent();

		setTimeout(() => {
			this.initDomInfo();
		}, 0);
	},
	methods: {
		initDomInfo() {
			const liRect = this.$refs.lrcList.children[0].getBoundingClientRect();
			this.domInfo.liHeight = liRect.height;
			const lrcBoxRect = this.$refs.lrcBox.getBoundingClientRect();
			this.domInfo.lrcBoxHeight = lrcBoxRect.height;
		},
		/**
		 * 查找当前歌词索引
		 */
		findCurrentIndex() {
			const currentTime = this.$refs.audio.currentTime;

			for (let index in this.lrcArr) {
				const lrc = this.lrcArr[index];
				if (lrc.time > currentTime) {
					this.currentIndex = index - 1;
					return;
				}
			}
			this.currentIndex = this.lrcArr.length - 1;
		},
		/**
		 * 高亮显示播放歌词
		 */
		highLightLrc() {
			// 确保每次调用 索引 是正确的
			this.findCurrentIndex();
			const oldLi = this.$refs.lrcList.querySelector('.lrc_word_active');
			// 考虑边界
			oldLi ? oldLi.classList.remove('lrc_word_active') : 1;
			if (this.currentIndex > -1) {
				const li = this.$refs.lrcList.children[this.currentIndex];
				li.classList.add('lrc_word_active');
			}
		},
		setUlOffset() {
			this.highLightLrc();
			let height = this.domInfo.liHeight * this.currentIndex + this.domInfo.liHeight / 2 - this.domInfo.lrcBoxHeight / 2;
			if (height < 0) {
				height = 0;
			}
			this.$refs.lrcList.style.transform = `translateY(-${height}px)`;
		},
		// 设置监听事件
		setListenerEvent() {
			this.$refs.audio.addEventListener('timeupdate', () => {
				this.setUlOffset();
			});
		},
		/**
		 * 格式化歌词，数据结构：{time: 秒数, word: 歌词}
		 */
		parseLrc() {
			const lrcLines = this.lrc.split('\n');
			lrcLines.forEach(item => {
				const parts = item.split(']');
				const lrcObj = {
					time: this.parseTime(parts[0].substring(1)),
					word: parts[1]
				};
				this.lrcArr.push(lrcObj);
			});
		},
		/**
		 * 格式化时间
		 * @param {string} timeStr 时间字符串
		 * @returns {number} 秒数
		 */
		parseTime(timeStr) {
			const parts = timeStr.split(':');
			return (parts[0] * 60 + (+parts[1])).toFixed(2) * 1;
		},
	}
};
</script>

<style lang="scss">
body {
	text-align: center;
	background-color: #000;
}

li {
	list-style: none;
}


audio {
	width: 80%;
	padding: 20px 0;
}

.lrc_box {
	height: calc(100vh - 120px);
	overflow: hidden;
}

.lrc_list {
	transition: all 0.5s;
}

.lrc_word {
	color: #555;
	font-size: 18px;
	line-height: 33px;
}

/* 效果歌词 */
.lrc_word_active {
	color: #fff;
	transform: scale(1.3);
	transition: all 0.3s;
}
</style>